package module.map.nodes
{
	import drongo.desktop.utils.CollisionsHelp;
	import drongo.model.propertys.ArrayProperty;
	import drongo.model.values.CollectionValue;
	
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.getTimer;
	
	import common.view.FGUIMediator;
	
	import fairygui.GComponent;
	
	import module.map.Operations;
	import module.map.model.ProjectModel;
	import module.map.model.Propertys;
	import module.map.operations.propertys.datas.ArrayPropertyChangeData;
	import module.map.operations.propertys.datas.PropertyChangeData;
	
	public class BaseNodeMediator extends FGUIMediator
	{
		[Inject]
		public var project:ProjectModel;
		
		/**
		 * 拖拽开始时的属性
		 */
		private static var startPropertys:Vector.<ArrayPropertyChangeData>=new Vector.<ArrayPropertyChangeData>();
		
		private static var viewStartPoint:Point=new Point();
		private static var startPoint:Point=new Point();
		private static var endPoint:Point=new Point();
		
		private static var lastPoint:Point=new Point();
		
		protected var stage:Stage;
		protected var nodes:ArrayProperty;
		protected var nodeData:CollectionValue;
		
		private var viewCom:GComponent;
		
		private var lastMouseDownTime:int=0;
		
		public function BaseNodeMediator()
		{
			super();
		}
		
		override public function initialize():void{
			super.initialize();
		}
		
		/**
		 * 初始化
		 */
		protected function Init(view:GComponent):void{
			this.viewCom=view;
			nodeData=this.viewCom.data as CollectionValue;
			this.stage=this.viewCom.displayListContainer.stage;
			this.nodes=this.project.currentMap.Get(Propertys.NODES) as ArrayProperty;
			
			this.AddEvents();
		}
		
		override public function destroy():void{
			super.destroy();
			this.RemoveEvents();
		}
		
		protected function AddEvents():void{
			this.stage.addEventListener(Event.ENTER_FRAME,this.Tick);
			this.viewCom.addEventListener(MouseEvent.MOUSE_DOWN,this.DragMouseDownHandler);
		}
		
		protected function RemoveEvents():void{
			this.stage.removeEventListener(Event.ENTER_FRAME,this.Tick);
			this.viewCom.removeEventListener(MouseEvent.MOUSE_DOWN,this.DragMouseDownHandler);
			
			this.stage.removeEventListener(MouseEvent.MOUSE_MOVE,this.DragMouseMoveHandler);
			this.stage.removeEventListener(MouseEvent.MOUSE_UP,this.DragMouseUpHandler);
		}
		
		protected function DragMouseDownHandler(e:MouseEvent):void{
			e.stopImmediatePropagation();
			e.stopPropagation();
			//拖拽处理
			var currentTime:int=getTimer();
			if(currentTime-lastMouseDownTime<300){
				this.stage.removeEventListener(MouseEvent.MOUSE_MOVE,this.DragMouseMoveHandler);
				this.stage.removeEventListener(MouseEvent.MOUSE_UP,this.DragMouseUpHandler);
				this.MouseDoubleClick(e);
				return;
			}
			lastMouseDownTime=currentTime;
			
			this.stage.addEventListener(MouseEvent.MOUSE_MOVE,this.DragMouseMoveHandler);
			this.stage.addEventListener(MouseEvent.MOUSE_UP,this.DragMouseUpHandler);
			
			viewStartPoint.x=this.viewCom.x;
			viewStartPoint.y=this.viewCom.y;
			
			startPoint.x=this.stage.mouseX;
			startPoint.y=this.stage.mouseY;
			
			//不是多选
			if(!e.shiftKey){
				this.project.currentMap.selector.resetSelectList();
			}
			if(this.project.currentMap.selector.selectedList.indexOf(this.nodeData)<0){
				this.project.currentMap.selector.push(this.nodeData);
			}
		}
		
		protected function MouseDoubleClick(e:MouseEvent):void{
			
		}
		
		protected function DragMouseMoveHandler(e:MouseEvent):void{
			e.stopImmediatePropagation();
			e.stopPropagation();
			
			endPoint.x=this.stage.mouseX;
			endPoint.y=this.stage.mouseY;
			if(CollisionsHelp.DistanceDetection(startPoint,endPoint,2)){
				return;
			}
			//记录开始操作时的各个节点的属性
			if(startPropertys.length==0){
				this.BuildOldPropertys();
			}
			var changeData:Object=this.CreatePropertyChangeData();
			this.project.undoSystem.executeOperation(Operations.ARRAY_PROPERTYS_CHANGE,changeData);
		}
		
		protected function DragMouseUpHandler(e:MouseEvent):void{
			e.stopImmediatePropagation();
			e.stopPropagation();
			this.stage.removeEventListener(MouseEvent.MOUSE_MOVE,this.DragMouseMoveHandler);
			this.stage.removeEventListener(MouseEvent.MOUSE_UP,this.DragMouseUpHandler);
			
			endPoint.x=this.stage.mouseX;
			endPoint.y=this.stage.mouseY;
			if(CollisionsHelp.DistanceDetection(startPoint,endPoint,2)){
				return;
			}
			
			var changeData:Object=this.CreatePropertyChangeData();
			changeData.oldPropertys=startPropertys.concat();
			this.project.undoSystem.executeOperation(Operations.ARRAY_PROPERTYS_CHANGE,changeData);
			// 清除
			startPropertys.length=0;
		}
		
		private function BuildOldPropertys():void{
			var selectList:Array=this.project.currentMap.selector.selectedList;
			if(selectList.length==0){
				return;
			}
			//老的属性
			startPropertys.length=0;
			var arrayChangeData:ArrayPropertyChangeData;
			var changeDataList:Vector.<PropertyChangeData>;
			
			var nodeData:CollectionValue;
			for each (nodeData in selectList) 
			{
				changeDataList=new Vector.<PropertyChangeData>();
				changeDataList.push(
					new PropertyChangeData(Propertys.X,nodeData.Get(Propertys.X).GetValue()),
					new PropertyChangeData(Propertys.Y,nodeData.Get(Propertys.Y).GetValue())
				);
				arrayChangeData=new ArrayPropertyChangeData(
					Propertys.ID,
					nodeData.Get(Propertys.ID).GetValue(),
					changeDataList
				);
				startPropertys.push(arrayChangeData);
			}
		}
		
		private function CreatePropertyChangeData():Object{
			if(startPropertys.length==0){
				throw new Error("老的属性没有记录！");
			}
			var result:Object={};
			var arrayChangeData:ArrayPropertyChangeData;
			var changeDataList:Vector.<PropertyChangeData>;
			var x:PropertyChangeData;
			var y:PropertyChangeData;
			//新的属性值
			var newPropertys:Vector.<ArrayPropertyChangeData>=new Vector.<ArrayPropertyChangeData>();
			for each (var item:ArrayPropertyChangeData in startPropertys) 
			{
				x=item.propertys[0];
				y=item.propertys[1];
				changeDataList=new Vector.<PropertyChangeData>();
				changeDataList.push(
					new PropertyChangeData(x.key,x.value+(endPoint.x-startPoint.x)),
					new PropertyChangeData(y.key,y.value+(endPoint.y-startPoint.y))
				);
				arrayChangeData=new ArrayPropertyChangeData(
					item.key,
					item.value,
					changeDataList
				);
				newPropertys.push(arrayChangeData);
			}
			result.parent=this.nodes;
			result.newPropertys=newPropertys;
			return result;
		}
	}
}